/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.meanzoft.minecraft_clone.world;

import org.meanzoft.minecraft_clone.block2.Block;
import org.meanzoft.minecraft_clone.test.VBO;

/**
 *
 * @author Meanz
 */
public class Chunk {

    private Block[][][] blocks;
    public VBO vbo;
    private int chunkX, chunkY, chunkZ;
    private boolean requestRebuild = true;
    private int state = 0;
    private int numBlocks = 0;

    public Chunk(int chunkX, int chunkY, int chunkZ) {
        this.chunkX = chunkX;
        this.chunkY = chunkY;
        this.chunkZ = chunkZ;
        blocks = new Block[16][16][16];
        vbo = new VBO();
    }

    public void addBlock(int x, int y, int z, Block block) {
        if(blocks[x - (chunkX * 16)][y - (chunkY * 16)][z - (chunkZ * 16)] == null) {
            numBlocks++;
        }
        blocks[x - (chunkX * 16)][y - (chunkY * 16)][z - (chunkZ * 16)] = block;
        requestRebuild = true;
    }

    public Block getBlock(int x, int y, int z) {
        return getLocalBlock(x - (chunkX * 16), y - (chunkY * 16), z - (chunkX * 16));
    }

    public Block getLocalBlock(int x, int y, int z) {
        if (x < 0 || y < 0 || z < 0
                || x > 15 || y > 15 || z > 15) {
            //return WorldManager.getWorld().getBlockAt(x + (chunkX * 16), y + (chunkY * 16), z + (chunkZ * 16));
            return null;
        }
        return blocks[x][y][z];
    }

    public void removeBlock(int x, int y, int z) {
        if(blocks[x - (chunkX * 16)][y - (chunkY * 16)][z - (chunkZ * 16)] != null) {
            numBlocks--;
        }
        blocks[x - (chunkX * 16)][y - (chunkY * 16)][z - (chunkZ * 16)] = null;
        requestRebuild = true;
    }
    
    public int getNumBlocks() {
        return numBlocks;
    }

    public Block[][][] getBlocks() {
        return blocks;
    }

    public void build() {
        if (state == 0) {
            requestRebuild = false;
            BlockCompiler.getBlockCompiler().add(this);
        } else if (state == 1) {
            vbo.compile();
            vbo.setBuilt(true);
            state = 0;
            requestRebuild = false;
        }
    }

    public void setState(int state) {
        this.state = state;
    }

    public int generateBlockData() {
        vbo.setBuilt(false);
        long s = System.currentTimeMillis();
        int bls = 0;
        vbo.clear();

        for (int x = 0; x < blocks.length; x++) {
            for (int y = 0; y < blocks.length; y++) {
                for (int z = 0; z < blocks.length; z++) {
                    if (blocks[x][y][z] != null) {
                        computeBlockData(x, y, z);
                        vbo.addBox(1f, 1f, x, y, z, blocks[x][y][z].getTextures(), blocks[x][y][z].blockData);
                        bls++;
                    }
                }
            }
        }
        setState(1);
        requestRebuild = true;
        return bls;
    }

    public void computeBlockData(int x, int y, int z) {
        if (blocks[x][y][z] == null) {
            return;
        }
        blocks[x][y][z].clearBlockData();
        if (getLocalBlock(x + 1, y, z) != null) {
            blocks[x][y][z].setBlockData(4);
        }
        if (getLocalBlock(x - 1, y, z) != null) {
            blocks[x][y][z].setBlockData(5);
        }
        if (getLocalBlock(x, y + 1, z) != null) {
            blocks[x][y][z].setBlockData(2);
        }
        if (getLocalBlock(x, y - 1, z) != null) {
            blocks[x][y][z].setBlockData(3);
        }
        if (getLocalBlock(x, y, z + 1) != null) {
            blocks[x][y][z].setBlockData(1);
        }
        if (getLocalBlock(x, y, z - 1) != null) {
            blocks[x][y][z].setBlockData(0);
        }
    }

    public boolean isRequestingRebuild() {
        return requestRebuild;
    }

    public void draw() {
        vbo.draw();
    }

    public int getChunkX() {
        return chunkX;
    }

    public int getChunkY() {
        return chunkY;
    }

    public int getChunkZ() {
        return chunkZ;
    }
}
